﻿#include <iostream>
#include <string>
#include <vector>
using namespace std;
/* 对象行为型模式
1.意图
将一个请求封装为一个对象，从而使你可用不同的请求对客户进行参数化，对请求排队或记录请求日志，以及支持可撤消的操作
2.别名
动作（Action),事务（Transaction)
3.适用性
当你有如下需求时，可使用Command模式：
a.像上面讨论的MenuItem对象那样，抽象出待执行的动作以参数化某对象。
b.在不同的时刻指定、排列和执行请求
c.支持取消操作
d.支持修改日志，这样当系统崩溃时，这些修改可以被重做一遍。
e.用构建在原语操作上的高层操作构造一个系统。
*/
//接收方厨师
class Cook
{
public:
	void MakeVegetable()
	{
		cout << "制作一盘蔬菜" << endl;
	}
	void MakeSteak()
	{
		cout << "制作一盘牛排" << endl;
	}
	void UnMakeVegetable()
	{
		cout << "取消一盘蔬菜" << endl;
	}
	void UnMakeSteak()
	{
		cout << "取消一盘牛排" << endl;
	}
};
//抽象命令类
class Command
{
public:
	Command(Cook* pcook) :pcook(pcook) {}
	virtual void ExecuteCommand() = 0;
	virtual void UnExecuteCommand() = 0;
protected:
	Cook* pcook;
};
//具体命令类
class MakeVegetableCommand :public Command
{
public:
	MakeVegetableCommand(Cook* pcook) :Command(pcook) {}
	void ExecuteCommand()
	{
		pcook->MakeVegetable();
	}
	void UnExecuteCommand()
	{
		pcook->UnMakeVegetable();
	}
};
class MakeSteakCommand :public Command
{
public:
	MakeSteakCommand(Cook* pcook) :Command(pcook) {}
	void ExecuteCommand()
	{
		pcook->MakeSteak();
	}
	void UnExecuteCommand()
	{
		pcook->UnMakeSteak();
	}
};
//发送方顾客点菜
class Order
{
public:
	void SetOrder(Command* command)
	{
		commands.push_back(command);
		cout << "点了一盘菜" << endl;
	}
	void UnOrder()
	{
		//取消点菜需要完善
		commands.pop_back();
		cout << "取消了一盘菜" << endl;
	}
	void Notify()
	{
		for (auto v : commands)
		{
			v->ExecuteCommand();
		}
	}
protected:
	vector<Command*> commands;

};
/*
int main()
{
	Cook* pcook = new Cook();
	MakeVegetableCommand* pmakeVe = new MakeVegetableCommand(pcook);
	MakeSteakCommand* pmakeSt = new MakeSteakCommand(pcook);
	Order* porder = new Order();
	porder->SetOrder(pmakeVe);
	porder->SetOrder(pmakeSt);
	porder->Notify();
	
	porder->UnOrder();
	porder->Notify();
	return 0;
}
*/